<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Api\Repositories\PostsRepositores;
use App\Jobs\CalculateFollowsNumJob;
use App\Jobs\CalculateLikesNumJob;
use App\Jobs\Posts\UpdatePostOnlyTextJob;
use App\Jobs\Posts\UpdatePostVideoIdJob;
use App\Lib\WeApp\WeApp;
use App\Models\Posts\WxPost;
use App\Models\User\WxUser;
use App\Models\Voter\WxVoter;
use App\Models\Voter\WxVoterPlayer;
use App\Models\Voter\WxVoterPlayerBallot;
use App\Models\Voter\WxVoterTemplate;
use App\Wen\Utils\FieldUtils;
use App\Wen\Utils\Settings;
use App\Wen\Utils\StrUtils;
use App\Wen\Utils\UserUtils;
use App\Wen\Utils\Utils;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class VoterController extends BaseController
{

    public function list(Request $request){
        $uid = $request->uid;

        if(_empty_($uid)){
            $uid = 0;
        }

        $user_id = _empty_default_($request->user_id, 0);
        $keyword = _empty_default_($request->keyword, '');
        $master = _empty_default_($request->master, 0);

        // player已经被系统占用
        $player = _empty_default_($request->player, 0);
        $playerd = _empty_default_($request->playerd, 0);
        if($playerd == 1){
            $player = 1;
        }

        $voted = _empty_default_($request->voted, 0);
        $template = _empty_default_($request->template, '');
        $isTenant = _empty_default_($request->isTenant, false);
        if(_empty_($isTenant)){
            $isTenant = false;
        }else{
            $isTenant = true;
        }

        if(is_string($template)){
            $template = explode(',', $template);
        }

        $orderBy = _empty_default_($request->orderBy, 'created_at');
        $order = _empty_default_($request->order, 'desc');

        if(!in_array($orderBy, ['created_at'])){
            $orderBy = 'created_at';
        }
        if(!in_array($order, ['desc', 'asc'])){
            $order = 'desc';
        }

        if(_empty_($user_id)){
            if($master == -1){
                $app_voter_tab = Settings::get('app_voter_tab', [], true);
                if($app_voter_tab && count($app_voter_tab) > 0){
                    $tab = $app_voter_tab[0];
                    $keyword = '';
                    $master = _array_key($tab, 'master', 0);
                    $player = _array_key($tab, 'player', 0);
                    $voted = _array_key($tab, 'voted', 0);
                    $orderBy = _array_key($tab, 'orderBy', 'created_at');
                    $order = _array_key($tab, 'order', 'desc');
                    $template = _array_key($tab, 'template', []);
                    if(is_string($template)){
                        $template = explode(',', $template);
                    }
                }else{
                    $keyword = '';
                    $master = 0;
                    $player = 0;
                    $voted = 0;
                    $orderBy = 'created_at';
                    $order = 'desc';
                    $template = [];
                }
            }
        }

        if(!is_array($template)){
            $template = [];
        }

        if(_empty_(end($template))){
            array_pop($template);
        }


        $query = WxVoter::where('is_exposure', 1);
        if($isTenant){
            global $__MINI_GLOBAL_TENANT_ID__;
            $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
        }
        if($keyword){
            $query = $query->where('status', 1);
            $query->where(function ($query) use ($keyword) {
                $query->orWhere('title', 'like', '%' . $keyword . '%')
                    ->orWhere('content', 'like', '%' . $keyword . '%')
                    ->orWhere('id', $keyword);
            });
        }else{
            if($template && count($template) > 0){
                $query = $query->whereIn('template_id', $template);
            }
            if($master == 1){
                if($user_id > 0){
                    $query = $query->where('user_id', $user_id);
                }else if($uid > 0){
                    $query = $query->where('user_id', $uid);
                }else{
                    $query = $query->where('id', '<=', 0);
                }
            }else{
                $query = $query->where('status', 1);
            }

            if($player == 1){
                if($user_id > 0){

                    $query = $query->whereIn('id', function ($query) use ($user_id) {
                        $query->select('voter_id')
                            ->from('wx_voter_player')
                            ->where('user_id', $user_id)
                            ->orderByDesc('created_at');
                    });
                }else if($uid > 0){
                    $query = $query->whereIn('id', function ($query) use ($uid) {
                        $query->select('voter_id')
                            ->from('wx_voter_player')
                            ->where('user_id', $uid)
                            ->orderByDesc('created_at');
                    });
                }else{
                    $query = $query->where('id', '<=', 0);
                }
            }
            if($voted == 1){
                if($uid > 0){
                    $query = $query->whereIn('id', function ($query) use ($uid) {
                        $query->select('voter_id')
                            ->from('wx_voter_player_ballot')
                            ->where('user_id', $uid)
                            ->groupBy('voter_id')
                            ->orderByDesc('created_at');
                    });
                }else{
                    $query = $query->where('id', '<=', 0);
                }
            }
        }


        $data = $query->orderBy('is_sticky', 'desc')->orderBy($orderBy, $order)->orderBy('id', 'desc')->simplePaginate(10);
        if($data){
            $data->map(function ($v) use ($uid){
                $this->voter_item_process($v, $uid);
                return $v;
            });
            return $this->success($data);
        }
        return $this->fail(200003);
    }

    public function detail(Request $request){
        $uid = $request->uid;
        $voter_id = _empty_default_($request->id, 0);
        if(_empty_($voter_id)){
            return $this->fail(200001);
        }
        $voter = WxVoter::where('id', $request->id)->first();
        if(!$voter){
            return $this->fail(200003);
        }
        $this->voter_item_process($voter, $uid);
        return $this->success($voter);
    }

    private function voter_item_process(WxVoter &$voter, $uid){
        global $__MINI_GLOBAL_IS_ADMIN_SUPER__;
        $voter->tabs = [
            ['name' => '参与'. $voter->player_called, 'action' => 'player'],
            ['name'=>'排行榜', 'action'=>'rank'],
            ['name'=>'简介', 'action'=>'brief'],
//            ['name'=>'互动', 'action'=>'comment']
        ];

        $result = DB::table('wx_voter_player_ballot')
            ->selectRaw(
                'SUM(num) as totalNum, ' .
                'COUNT(DISTINCT user_id) as uniqueUserCount'
            )
            ->where('voter_id', $voter->id)
            ->first();


        $voter->ballot_total = $result->totalNum ?: 0;
        $voter->player_count = WxVoterPlayer::where('voter_id', $voter->id)->where('status', 1)->count();
        $voter->user_count = $result->uniqueUserCount ?: 0;
        if($uid > 0){
            $voter->user_ballot_rest = $this->get_user_voter_rest_ballot($voter, $uid);
        }else{
            // user_day_limit,user_total_limit
            if($voter->user_total_limit > 0){
                $voter->user_ballot_rest = $voter->user_total_limit;
            }else{
                $voter->user_ballot_rest = $voter->user_day_limit;
            }
        }

        if($voter->user_total_limit > 0){
            $voter->user_ballot_tip = '总共拥有'.$voter->user_total_limit.$voter->unit_called.'，剩余' .$voter->user_ballot_rest.$voter->unit_called;
        }else{
            $voter->user_ballot_tip = '每日可投'.$voter->user_day_limit.$voter->unit_called.'，今日剩余'.$voter->user_ballot_rest.$voter->unit_called;
        }


        if($uid > 0){
            if(is_object_user_special($uid, $voter->tenant_id, true) || $uid == $voter->user_id){
                if($voter->player_count > 0){
                    $voter->action_sheets = ['删除'];
                }else{
                    $voter->action_sheets = ['编辑', '删除'];
                }
            }
        }

    }


    public function voter_process(Request $request){
        $type = _empty_default_($request->type, '');
        if($type == 'push' || $type == 'update'){
            return $this->voter_push($request);
        }else if($type == 'push_player'){
            return $this->voter_player_push($request);
        }else if($type == 'player_ballot'){
            return $this->player_ballot($request);
        }else if($type == 'delete'){
            return $this->voter_delete($request);
        }else if($type == 'echo'){
            return $this->voter_echo($request);
        }else if($type == 'voter_share'){
            return $this->voter_share($request);
        }
    }

    private function voter_share(Request &$request){
        $uid = _empty_default_($request->uid, 0);
        $voter_id_ = _abs(_empty_default_($request->voter_id, 0));
        global $__MINI_GLOBAL_DEVICE__;
        if(_empty_($voter_id_)){
            return $this->fail(200001);
        }
        global $__MINI_GLOBAL_PAYCODE_21__,$__MINI_GLOBAL_IS_ADMIN_SUPER__;
        $new_app = new WeApp();
        $wxlink = $new_app->getWxLink();
        $voter = WxVoter::find($voter_id_);
        if(!$voter){
            return $this->fail(200003);
        }
        $voter_user_id = $voter->user_id;
        $voter_title = StrUtils::limit($voter->title);

        $s_content = preg_replace("/<(img|video).*?src[^\'\"]+[\'\"]([^\"\']+)[^>]+>/is", '', $voter->content);
        $s_content = trim_all_space(strip_tags(html_entity_decode($s_content)), true);

        $this->voter_item_process($voter, $uid);

        $result = [
            'user' => [],
            'url' => '',
            'social' => [

            ],
            'other' => [],
            // 临时加下
            'current_page' => 1
        ];

        if($uid && $uid > 0){
            if($__MINI_GLOBAL_PAYCODE_21__){
                if(!is_mini_examine_mode(11)){
                    $data = DB::table('wx_user')
                        ->whereIn('id', function ($query) use ($uid) {
                            $query->select('object_id')
                                ->from('wx_chat')
                                ->where('user_id', $uid)
                                ->groupBy('object_id')
                                ->orderByDesc('created_at');
                        })->simplePaginate(10, FieldUtils::userInfoColums());
                    if($data->isEmpty()){
                        $data = WxUser::where('is_official', 1)->simplePaginate(10, FieldUtils::userInfoColums());
                    }
                    $result['user'] = $data;
                }
            }

        }

        global $__MINI_GLOBAL_TENANT_ID__;
        if(Settings::get('app_h5_home', '')){
            $result['url'] = Settings::get('app_h5_home', '').'/#/pagesV/voter/detail/detail?id='.$voter->id . '&fph=1&from_user=' .$uid. '&tenant=' . $__MINI_GLOBAL_TENANT_ID__;
        }else{
            $result['url'] = env('APP_URL');
        }

        $the_only_path = '/pagesV/voter/detail/detail?id=' . $voter->id. '&fph=1&from_user=' .$uid. '&tenant=' . $__MINI_GLOBAL_TENANT_ID__;

        $share_types = Settings::get('app_voter_social_share_types', []);
        foreach (['refer', 'wechat', 'timeline', 'qq', 'qzone', 'weibo'] as $key){
            if(!in_array($key, $share_types)){
                continue;
            }
            if($key == 'refer'){
                if($__MINI_GLOBAL_PAYCODE_21__){
                    $result['social'][] = [
                        'action' => 'slider',
                        'color' => Settings::get('--color-primary', '#FC3A72'),
                        'text' => '站内转发',
                        'icon' => 'mini-icon mini-zhanneizhuanfa',
                        'unicode' => 'e699',
                        'target_type' => 6,
                        'target_id' => '/pages/creat/index/creat?voter_id=' . $voter->id
                    ];
                }
            }else if($key == 'wechat'){
                $result['social'][] = [
                    'action' => 'wechat',
                    'color' => '#57be6a',
                    'text' => '微信好友',
                    'icon' => 'mini-icon mini-weixin',
                    'unicode' => 'e60b',
                    'share' => json_encode([
                        'provider' => 'weixin',
                        'type' => _empty_(Settings::get('app_meta_appid',  '')) ? 0 : 5,
                        'title' => $voter_title,
                        'scene' => 'WXSceneSession',
                        'href' => $result['url'],
                        'imageUrl' => $voter->pic,
                        'miniProgram' => [
                            'id' => Settings::get('app_meta_appid',  ''),
                            'path' => $the_only_path,
                            'type' => 0,
                            'webUrl' => $result['url']
                        ]
                    ]),

                ];
            }else if($key == 'timeline'){
                if($__MINI_GLOBAL_DEVICE__ != 'mp'){
                    $result['social'][] = [
                        'action' => 'timeline',
                        'color' => '#80cc46',
                        'text' => '朋友圈',
                        'icon' => 'mini-icon mini-pengyouquan1',
                        'unicode' => 'e669',
                        'share' => json_encode([
                            'provider' => 'weixin',
                            'type' => 0,
                            'title' => $voter_title,
                            'summary' => $s_content,
                            'scene' => 'WXSceneTimeline',
                            'href' => $result['url'],
                            'imageUrl' => $voter->pic,
                            'miniProgram' => [
                                'id' => Settings::get('app_meta_appid',  ''),
                                'path' => $the_only_path,
                                'type' => 0,
                                'webUrl' => $result['url']
                            ]
                        ])
                    ];
                }
            }else if($key == 'qq'){
                if(!_empty_(Settings::get('app_qq_app_appid', ''))){
                    if($__MINI_GLOBAL_DEVICE__ != 'mp') {
                        $result['social'][] = [
                            'action' => 'qq',
                            'color' => '#54b4ef',
                            'text' => 'QQ好友',
                            'icon' => 'mini-icon mini-qq1',
                            'unicode' => 'e66c',
                            'share' => json_encode([
                                'provider' => 'qq',
                                'type' => 1,
                                'title' => $voter_title,
                                'summary' => $s_content,
                                'href' => $result['url'],
                                'imageUrl' => $voter->pic
                            ])

                        ];
                    }
                }
            }else if($key == 'qzone'){
                if(!_empty_(Settings::get('app_qq_app_appid', ''))){
                    if($__MINI_GLOBAL_DEVICE__ != 'mp') {
                        $result['social'][] = [
                            'action' => 'qzone',
                            'color' => '#f7cf46',
                            'text' => 'QQ空间',
                            'icon' => 'mini-icon mini-Rrl_s_112',
                            'unicode' => 'e62a',
                            'share' => json_encode([
                                'provider' => 'qq',
                                'type' => 1,
                                'title' => $voter_title,
                                'href' => $result['url'],
                                'imageUrl' => $voter->pic
                            ])
                        ];
                    }
                }
            }else if($key == 'weibo'){
                if(!_empty_(Settings::get('app_weibo_app_appid', ''))){
                    if($__MINI_GLOBAL_DEVICE__ != 'mp') {
                        $result['social'][] = [
                            'action' => 'weibo',
                            'color' => '#d4382a',
                            'text' => '微博',
                            'icon' => 'mini-icon mini-weibo',
                            'unicode' => 'e73c',
                            'share' => json_encode([
                                'provider' => 'sinaweibo',
                                'type' => 0,
                                'title' => $voter_title,
                                'href' => $result['url'],
                                'imageUrl' => $voter->pic
                            ])

                        ];
                    }
                }
            }
        }

        $system_types = Settings::get('app_voter_social_system_types', ['edit', 'copyUrl', 'report' ]);
        // promotion
        foreach (['edit', 'copyUrl', 'report'] as $key){
            if(!in_array($key, $system_types)){
                continue;
            }
            if($key == 'showCode'){
                $result['other'][] = [
                    'text' => '生成海报',
                    'icon' => 'mini-icon mini-shengchenghaibao',
                    'action' => 'slider',
                    'unicode' => 'e697',
                    'target_type' => 6,
                    'target_id' => '/pagesZ/organize-voter/poster/poster?id=' . $voter->id
                ];
            }else if($key == 'edit'){
                if((is_array($voter->action_sheets) && in_array('编辑', $voter->action_sheets)) || $__MINI_GLOBAL_IS_ADMIN_SUPER__){
                    $result['other'][] = [
                        'text' => '编辑',
                        'icon' => 'mini-icon mini-xie',
                        'unicode' => 'e6fd',
                        'action' => 'slider',
                        'target_type' => 6,
                        'target_id' => '/pagesV/voter/creat/creat?voter_id=' . $voter->id
                    ];
                }
            }else if($key == 'copyUrl'){
                try {
                    $the_only_path_arr = explode('?', $the_only_path);
                    $url_link = Cache::remember(md5($the_only_path), 3600 * 24, function () use (&$wxlink, &$the_only_path_arr){
                        return $wxlink->genWxUrllink($the_only_path_arr[0] ?? '', $the_only_path_arr[1] ?? '');
                    });
                }catch (\Exception $e){
                    $url_link = $result['url'];
                }

                $voter_group_text = '';

                $result['other'][] = [
                    'text' => '复制链接',
                    'icon' => 'mini-icon mini-fuzhilianjie',
                    'unicode' => 'e691',
                    'action' => 'copyUrl',
                    'copy' => '🌟'.$voter_title.'

⏰活动时间：'.$voter->start_time .' 至 '.$voter->end_time.'
📍报名'.$voter->player_called.'：'.$voter->player_count.'
🏁发起人：'.$voter->master_user_name.'
'.$voter_group_text.'
- - - - - - - - - - - - - - - - - - - -
🌟选票活动：'.$url_link.'
',
                ];
            }else if($key == 'report'){
                if($voter_user_id != $uid){
                    $result['other'][] = [
                        'text' => '举报',
                        'icon' => 'mini-icon mini-jubao',
                        'unicode' => 'e694',
                        'action' => 'slider',
                        'target_type' => 6,
                        'target_id' => '/pages/common/report?type=6&object_id=' . $voter->id
                    ];
                }
            }
        }

        if((is_array($voter->action_sheets) && in_array('删除', $voter->action_sheets)) || $__MINI_GLOBAL_IS_ADMIN_SUPER__){
            $result['other'][] = [
                'text' => '删除',
                'icon' => 'mini-icon mini-shanchu211',
                'unicode' => 'e6f3',
                'action' => 'delete',
                'voter_id' => $voter->id
            ];
        }

//        _logger_(__file__, __line__, $result);
        return $this->success($result);
    }



    private function voter_echo(Request &$request){
        $uid = $request->uid;
        if(_empty_($uid)){
            return $this->fail(503002);
        }
        $voter_id = (int)(_empty_default_($request->voter_id, 0));
        if(_empty_($voter_id)){
            return $this->fail(200001);
        }
        global $__MINI_GLOBAL_IS_ADMIN_SUPER__;
        $the_voter = WxVoter::find($voter_id);
        if(_empty_($the_voter)){
            return $this->fail(200003);
        }
        if(!$__MINI_GLOBAL_IS_ADMIN_SUPER__ && $the_voter->user_id != $uid){
            return $this->fail(200000);
        }

        if ($the_voter->user_total_limit > 0) {
            // 总限制存在
            $voteTimes = [1, $the_voter->user_total_limit - 1];
        } elseif ($the_voter->user_day_limit > 0) {
            // 每日限制存在
            $voteTimes = [0, $the_voter->user_day_limit - 1];
        } else {
            // 无限制
            $voteTimes = [0, 0];
        }


        $start_time = $the_voter->start_time;
        $end_time = $the_voter->end_time;
        $enter_start_time = $the_voter->enter_start_time;
        $enter_end_time = $the_voter->enter_end_time;

// 将时间转为秒
        $start_time_unix = strtotime($start_time);
        $end_time_unix = strtotime($end_time);
        $enter_start_time_unix = strtotime($enter_start_time);
        $enter_end_time_unix = strtotime($enter_end_time);

// 将时间转换为毫秒
        $start_time_ms = $start_time_unix * 1000;
        $end_time_ms = $end_time_unix * 1000;
        $enter_start_time_ms = $enter_start_time_unix * 1000;
        $enter_end_time_ms = $enter_end_time_unix * 1000;

// 验证时间戳长度
        if (strlen((string)$start_time_ms) != 13 || strlen((string)$end_time_ms) != 13) {
            return $this->fail(200004, [], '时间戳格式错误');
        }

        $res_obj = [
            'type' => 'update',
            'id' => $the_voter->id,
            'master_user_avatar' => $the_voter->master_user_avatar,
            'master_user_name' => $the_voter->master_user_name,
            'template_id' => $the_voter->template_id,
            'title' => $the_voter->title,
            'notice' => $the_voter->notice,
            'vcontent' => $the_voter->content, // 由于传输参数不能是 content，加了个v
            'banners' => $the_voter->banners,
            'is_open_enter' => $the_voter->is_open_enter,
            'is_exposure' => $the_voter->is_exposure,
            'is_open_vote_comment' => $the_voter->is_open_vote_comment,
            'is_open_player_comment' => $the_voter->is_open_player_comment,
            'is_can_be_anonymous' => $the_voter->is_can_be_anonymous,
            'is_hide_rank' => $the_voter->is_hide_rank,
            'is_hide_vote_record' => $the_voter->is_hide_vote_record,
            'is_hide_player_count' => $the_voter->is_hide_player_count,
            'music_url' => $the_voter->music_url,
            'music_name' => $the_voter->music_name,
            'is_music_auto' => $the_voter->is_music_auto,
            'start_time' => $start_time_ms,
            'end_time' => $end_time_ms,
            'enter_start_time' => $enter_start_time_ms,
            'enter_end_time' => $enter_end_time_ms,
            'user_day_limit' => $the_voter->user_day_limit,
            'user_total_limit' => $the_voter->user_total_limit,
            'player_called' => $the_voter->player_called,
            'unit_called' => $the_voter->unit_called,
            'main_background_image' => $the_voter->main_background_image,
            'user_background_image' => $the_voter->user_background_image,
            'background_color' => $the_voter->background_color,
            'text_color' => $the_voter->text_color,
            'main_color' => $the_voter->main_color,
            'button_bg_color' => $the_voter->button_bg_color,
            'button_text_color' => $the_voter->button_text_color,
            'text_navigation_bar_color' => $the_voter->text_navigation_bar_color,
            'voteTimes' => $voteTimes,
        ];
        return $this->success($res_obj);
    }


    private function voter_delete(Request &$request){
        $uid = $request->uid;
        if(_empty_($uid)){
            return $this->fail(503002);
        }
        $voter_id = (int)(_empty_default_($request->voter_id, 0));
        if(_empty_($voter_id)){
            return $this->fail(200001);
        }
        $the_voter = WxVoter::find($voter_id);
        if(_empty_($the_voter)){
            return $this->fail(200003);
        }

        if(!is_object_user_special($uid, $the_voter->tenant_id, true) && $the_voter->user_id != $uid){
            return $this->fail(200000);
        }

        DB::beginTransaction();
        try {
            // todo:
            WxVoter::where('id', $the_voter->id)->delete();
            WxVoterPlayer::where('voter_id', $the_voter->id)->delete();
            WxPost::where('voter_id', $the_voter->id)->update(['is_examine'=>2, 'overrule_content'=>'选票已被删除']);
            DB::commit();
            return $this->success();
        } catch (\Exception $e) {
            DB::rollBack();
            _logger_(__file__, __line__, $e->getMessage());
            return $this->fail(200002);
        }
    }

    private function player_ballot(Request $request){
        $uid = $request->uid;
        $voter_id = _empty_default_($request->voter_id, 0);
        $player_id = _empty_default_($request->player_id, 0);
        $num = _empty_default_($request->num, 0);

        if(_empty_($voter_id) || _empty_($player_id) || _empty_($num)){
            return $this->fail(200001);
        }

        $voter = WxVoter::find($voter_id);
        if ($voter) {
            // 使用Carbon进行日期时间比较
            $now = Carbon::now();
            $endTime = Carbon::parse($voter->end_time);
            $startTime = Carbon::parse($voter->start_time);

            if ($now->gt($endTime)) {
                // 当前时间已超过end_time
                return $this->fail(200046, [], '当前时间已超过投票截止时间');
            } else {
                // 当前时间未超过end_time
            }

            if ($now->gt($startTime)) {
                // 当前时间已超过start_time

            } else {
                // 当前时间未超过start_time
                return $this->fail(200046, [], '当前时间未达到投票开始时间');
            }
        } else {
            return $this->fail(200003, [], '选票活动不存在');
        }

        $player = WxVoterPlayer::find($player_id);
        if(!$player){
            return $this->fail(200003, [], '选手不存在');
        }

        $rest = $this->get_user_voter_rest_ballot($voter, $uid);
        if($rest < $num){
            return $this->fail(200046, [], '您剩余的票数为'.$rest.'，不足以本次投票');
        }

        DB::beginTransaction();
        try {
            // todo:
            $ballot = new WxVoterPlayerBallot();
            $ballot->user_id = $uid;
            $ballot->voter_id = $voter->id;
            $ballot->player_id = $player->id;
            $ballot->num = $num;
            $r = $ballot->save();
            if($r){
                DB::commit();
                Cache::forget('user:gird_voter:tip:'.$uid);
                return $this->success();
            }
            DB::rollBack();
            return $this->fail(200002);
        } catch (\Exception $e) {
            DB::rollBack();
            _logger_(__file__, __line__, $e->getMessage());
            return $this->fail(200002);
        }

    }

    private function get_user_voter_rest_ballot(WxVoter $voter, $user_id){
        $voter_id = $voter->id; // 需要查询的voter_id

        $todayStart = Carbon::today()->startOfDay();
        $todayEnd = Carbon::today()->endOfDay();
        $sums = WxVoterPlayerBallot::selectRaw('
        SUM(num) as historySum,
        SUM(CASE WHEN created_at BETWEEN ? AND ? THEN num ELSE 0 END) as todaySum',
            [$todayStart, $todayEnd])
            ->where('user_id', $user_id)
            ->where('voter_id', $voter_id)
            ->first();
        // user_day_limit,user_total_limit
        if($voter->user_total_limit > 0){
            $rest = $voter->user_total_limit - $sums->historySum;
        }else{
            $rest = $voter->user_day_limit - $sums->todaySum;
        }
        if($rest >= 0){
            return $rest;
        }
        return 0;
    }

    private function voter_player_push(Request $request){
        global $__MINI_GLOBAL_PAYCODE_33__;
        if(!$__MINI_GLOBAL_PAYCODE_33__){
            return $this->fail(200000, [], '付费33 未授权');
        }

        $voter_id = _empty_default_($request->voter_id, 0);
        $uid = $request->uid;
        $show_name = _empty_default_($request->show_name, '');
        $work_name = _empty_default_($request->work_name, '');
        $work_desc = _empty_default_($request->work_desc, '');
        $video_url = _empty_default_($request->video_url, '');
        $video_cover = _empty_default_($request->video_cover, '');
        $img_urls = _empty_default_($request->img_urls, []);
        $contact_text = _empty_default_($request->contact_text, '');

        // 判断当前时间是否在报名截止时间
        $wxVoter = WxVoter::find($voter_id);
        if ($wxVoter) {
            // 使用Carbon进行日期时间比较
            $now = Carbon::now();
            $enterEndTime = Carbon::parse($wxVoter->enter_end_time);
            $enterStartTime = Carbon::parse($wxVoter->enter_start_time);

            if ($now->gt($enterEndTime)) {
                // 当前时间已超过enter_end_time
                return $this->fail(200046, [], '当前时间已超过报名截止时间');
            } else {
                // 当前时间未超过enter_end_time
            }

            if ($now->gt($enterStartTime)) {
                // 当前时间已超过enter_start_time

            } else {
                // 当前时间未超过enter_start_time
                return $this->fail(200046, [], '当前时间未达到报名开始时间');
            }
        } else {
            return $this->fail(200003, [], '选票活动不存在');
        }

        if(_empty_($show_name)){
            return $this->fail(200004, [], '请输入展示名字');
        }

        $img_state_change_list = [];
        $img_urls__ = [];
        if(is_string($img_urls)){
            $img_urls = json_decode($img_urls, true);
        }
        if(_empty_($img_urls) || !is_array($img_urls)){
            return $this->fail(200004, [], '未上传图片');
        }
        foreach ($img_urls as $url){
            $url = stripslashes($url);
            $img_urls__[] = $url;
            $img_state_change_list[] = $url;
        }

        if(_empty_($video_url)){
            $video_cover = '';
        }

        if($video_cover){
            $img_state_change_list[] = $video_cover;
            $img_state_change_list[] = $video_url;
        }

        $voterplayer = WxVoterPlayer::withTrashed()->where('user_id', $uid)->where('voter_id', $voter_id)->first();
        if($voterplayer){
            if ($voterplayer->trashed()) {
                $voterplayer->restore();
            }
            return $this->fail(200010, [], '你已经报名过了，请联系管理员');
        }

        $current_relative_id = WxVoterPlayer::withTrashed()->where('voter_id', $voter_id)->max('relative_id');
        if(_empty_($current_relative_id)){
            $current_relative_id = 0;
        }

        DB::beginTransaction();
        try {
            // todo:
            $voterplayer = new WxVoterPlayer();
            $voterplayer->show_name = $show_name;
            $voterplayer->voter_id = $voter_id;
            $voterplayer->relative_id = $current_relative_id + 1;
            $voterplayer->user_id = $uid;
            $voterplayer->work_name = $work_name;
            $voterplayer->work_desc = $work_desc;
            $voterplayer->video_url = $video_url;
            $voterplayer->video_cover = $video_cover;
            $voterplayer->contact_text = $contact_text;
            $voterplayer->img_urls = json_encode($img_urls__);
            $voterplayer->status = 0;
            $r = $voterplayer->save();
            if($r){
                Utils::image_state_change($img_state_change_list, 1);
                UserUtils::assistant_notice_review(105, $voterplayer->id);
                UserUtils::assistant_notice_review(105, $voterplayer->id, $wxVoter->user_id);
                DB::commit();
                Cache::forget('user:gird_voter:tip:'.$uid);
                return $this->success($voter_id);
            }
            DB::rollBack();
            return $this->fail(200002);
        } catch (\Exception $e) {
            DB::rollBack();
            _logger_(__file__, __line__, $e->getMessage());
            return $this->fail(200002);
        }

    }

    private function voter_push(Request $request){
        global $__MINI_GLOBAL_TENANT_ID__,$__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_IS_ADMIN_SUPER__;

        $uid = $request->uid;
        $update_voter_id = _empty_default_($request->id, 0);
        if($update_voter_id > 0){
            $the_voter = WxVoter::find($update_voter_id);
            if(_empty_($the_voter)){
                return $this->fail(200003);
            }
            if(!is_object_user_special($uid, $the_voter->tenant_id, true) && $the_voter->user_id != $uid){
                return $this->fail(200000);
            }
            if(WxVoterPlayer::where('voter_id', $the_voter->id)->where('status', 1)->count() > 0){
                return $this->fail(200010, [], '已经有人报名的选票不能二次修改');
            }
        }
        $title = _empty_default_($request->title, '');
        $notice = _empty_default_($request->notice, '');
        $content = _empty_default_($request->vcontent, '');
        $banners = _empty_default_($request->banners, '');
        $start_time = _empty_default_($request->start_time, 0);
        $end_time = _empty_default_($request->end_time, 0);
        $template_id = _empty_default_($request->template_id, 0);
        $voteTimes = _empty_default_($request->voteTimes, []);
        $master_user_avatar = _empty_default_($request->master_user_avatar, '');
        $master_user_name = _empty_default_($request->master_user_name, '');

        $is_exposure = _empty_($request->is_exposure) ? 0 : 1;

        if(_empty_($title) || _empty_($content) || _empty_($template_id)){
            return $this->fail(200001);
        }

        if(is_string($banners)){
            $banners = json_decode($banners, true);
        }else if(is_array($banners)){

        }else{
            return $this->fail(200004);
        }
        if(_empty_($banners) || !is_array($banners) || _empty_($banners)){
            return $this->fail(200001);
        }

        if(_empty_($start_time) || _empty_($end_time)){
            return $this->fail(200001);
        }

        if(strlen($start_time) != 13 || strlen($end_time) != 13){
            return $this->fail(200004);
        }

        $start_time = floor($start_time / 1000);
        $end_time = floor($end_time / 1000);

        // 检查合理性-毫秒
        if($end_time - $start_time < 10){
            return $this->fail(200004, [], '无法创建持续时间不足10秒钟的选票');
        }

        if($end_time < time()){
            return $this->fail(200004, [], '选票结束时间小于当前时间');
        }

        // master
        $master = WxUser::find($uid);
        $template = WxVoterTemplate::find($template_id);
        if(!$template){
            return $this->fail(200004, [], '选票模板不存在');
        }

        $img_state_change_list = [];
        $img_urls = [];
        foreach ($banners as $banner){
            if(strpos($banner, 'http') === 0){
                $banner = stripslashes($banner);
                $img_urls[] = $banner;
                $img_state_change_list[] = $banner;
            }
        }

        if(is_string($voteTimes)){
            $voteTimes = json_decode($voteTimes, true);
        }
        if(_empty_($voteTimes) || !is_array($voteTimes) || count($voteTimes) != 2){
            return $this->fail(200004, [], '选票次数限制错误');
        }
        if(!in_array($voteTimes[0], [0, 1])){
            return $this->fail(200004, [], '选票次数限制错误0');
        }

        // 1-50次
        if($voteTimes[1] < 0 || $voteTimes[1] > 49){
            return $this->fail(200004, [], '选票次数限制错误1');
        }

        $voteTimes[1] += 1;

        if($master_user_avatar){
            $img_state_change_list[] = $master_user_avatar;
        }

        DB::beginTransaction();
        try {
            // todo:
            if($update_voter_id > 0){
                $voter = WxVoter::find($update_voter_id);
            }else{
                $voter = new WxVoter();
                $voter->template_id = $template->id;
                $voter->main_background_image = $template->main_background_image;
                $voter->user_background_image = $template->user_background_image;
                $voter->background_color = $template->background_color;
                $voter->text_color = $template->text_color;
                $voter->main_color = $template->main_color;
                $voter->button_bg_color = $template->button_bg_color;
                $voter->button_text_color = $template->button_text_color;
                $voter->text_navigation_bar_color = $template->text_navigation_bar_color;
                if($__MINI_GLOBAL_TENANT_ID__ > 0){
                    $voter->tenant_id = $__MINI_GLOBAL_TENANT_ID__;
                }
            }

            $voter->user_id = $master->id;
            $voter->master_user_avatar = stripslashes($master_user_avatar) ?: $master->user_avatar;
            $voter->master_user_name = $master_user_name ?: $master->user_avatar;

            $voter->title = $title;
            $voter->notice = $notice;
            $voter->content = $content;
            $voter->banners = json_encode($img_urls);

            $voter->start_time = timetostr($start_time);
            $voter->end_time = timetostr($end_time);

            $voter->enter_start_time = timetostr($start_time);
            $voter->enter_end_time = timetostr($end_time);

            if($voteTimes[0] == 1){
                $voter->user_total_limit = $voteTimes[1];
            }else{
                $voter->user_day_limit = $voteTimes[1];
            }

            $voter->player_called = '选手';
            $voter->unit_called = '票';

            $voter->is_exposure = $is_exposure;

            $voter->status = $update_voter_id > 0 ? 1 : 0;
            $r = $voter->save();
            if($r){
                $voter_id = $voter->id;
                Utils::image_state_change($img_state_change_list, 1);
                if($update_voter_id > 0){

                }else{
                    if($is_exposure == 1){
                        $post_id = PostsRepositores::add($master->id, 1, '', '我发布了一个选票~', 0, null, null, !_empty_('') ? [['url'=>'']] : [], '', null, null, null, null,
                            null, null, null, null, $__MINI_GLOBAL_DEVICE__, null, null, null, [], null, false, $voter->id);
                        if ($post_id) {
                            CalculateLikesNumJob::dispatch($post_id);
                            UpdatePostVideoIdJob::dispatch($post_id);
                            CalculateFollowsNumJob::dispatch($uid);
                            Redis::sadd('realtime:post:set', $post_id);
                            UpdatePostOnlyTextJob::dispatch(0);
                            UserUtils::add_user_experience($uid, 15, 10);
                        }
                    }
                    UserUtils::assistant_notice_review(104, $voter_id);
                }
                DB::commit();
                Cache::forget('user:gird_voter:tip:'.$master->id);
                return $this->success($voter_id);
            }
            DB::rollBack();
            return $this->fail(200002);
        } catch (\Exception $e) {
            DB::rollBack();
            _logger_(__file__, __line__, $e->getMessage());
            return $this->fail(200002);
        }
    }

    public function template_info(Request $request){
        $template_id = _empty_default_($request->id, 0);
        if(_empty_($template_id)){
            return $this->fail(200001);
        }
        $template = WxVoterTemplate::find($template_id);
        if($template){
            return $this->success($template);
        }
        return $this->fail(200003);
    }

    public function player_detail(Request $request){
        $uid = $request->uid;
        $player_id = _empty_default_($request->id, 0);
        if(_empty_($player_id)){
            return $this->fail(200001);
        }
        $player = WxVoterPlayer::find($player_id);
        if(!$player){
            return $this->fail(200003);
        }
        $voter_id = $player->voter_id;
        $voter = WxVoter::find($voter_id);
        if(!$voter){
            return $this->fail(200003);
        }
        $player->user = UserUtils::get_cached_user($player->user_id);
        $this->voter_item_process($voter, $uid);
        $player->voter = $voter;
        return $this->success($player);
    }

    public function player_list(Request $request){
        $voter_id = _empty_default_($request->voter_id, 0);
        if(_empty_($voter_id)){
            return $this->fail(200001);
        }
        $keyword = _empty_default_($request->keyword, '');
        $orderBy = _empty_default_($request->orderBy, 'created_at');
        $order = _empty_default_($request->order, 'desc');

        if(!in_array($orderBy, ['created_at', 'num', 'default'])){
            $orderBy = 'created_at';
        }
        if(!in_array($order, ['desc', 'asc'])){
            $order = 'desc';
        }

        if($orderBy == 'created_at' || $orderBy == 'default'){

            $query = WxVoterPlayer::where('status', 1);
            if($keyword){
                $query = $query->where(function ($query_) use ($keyword) {
                    $query_->orWhere('relative_id', $keyword)
                        ->orWhere('show_name', 'like', '%' . $keyword . '%');
                });
            }

            if($orderBy == 'created_at'){
                $query = $query->orderBy($orderBy, $order);
            }

            if($voter_id){
                $query = $query->where('voter_id', $voter_id);
            }

        }else if($orderBy == 'num'){
            $query = WxVoterPlayer::select('wx_voter_player.*')
                ->leftJoin('wx_voter_player_ballot', 'wx_voter_player.id', '=', 'wx_voter_player_ballot.player_id')
                ->where([['wx_voter_player.status', '=', 1], ['wx_voter_player.voter_id', '=', $voter_id]])
                ->groupBy('wx_voter_player.id')
                ->orderByDesc(
                    DB::raw('SUM(wx_voter_player_ballot.num)')
                );
        }

        $players = $query->simplePaginate(10);
        if($players){
            $players->map(function ($v, $k){
                $this->player_process($v);
                return $v;
            });
            return $this->success($players);
        }
        return $this->fail(200003);
    }

    private function player_process(WxVoterPlayer &$player){
        if($player->video_cover){
            $player->pic = $player->video_cover . '?imageMogr2/thumbnail/1000x';
        }else if($player->img_urls){
            $player->pic = $player->img_urls[0] . '?imageMogr2/thumbnail/1000x';
        }
        $player->ballot_total = WxVoterPlayerBallot::where('voter_id', $player->voter_id)->where('player_id', $player->id)->sum('num');
        $player->user = UserUtils::get_cached_user($player->user_id);
    }

    public function template_list(Request $request){
        $templates = WxVoterTemplate::where('status', 1)->orderBy('created_at','desc')->select('id','name','cover')->simplePaginate(6);
        if($templates){
            return $this->success($templates);
        }
        return $this->fail(200003);
    }

}
